package com.lin.execute;

import com.lin.entity.Npc;
import com.lin.entity.Room;
import com.lin.entity.Scene;
import com.lin.entity.Waypoint;
import com.lin.info.ScreenInfo;
import com.net.Network;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;

import static com.sun.xml.internal.ws.spi.db.BindingContextFactory.LOGGER;

public class ScreenUtil {
    public static void saveScreen(Scene Scene){
        System.out.println(Scene);
        final boolean[] wait = {true};
        Network network = new Network();
        network.saveScreen(new Network.Callback() {
            @Override
            public void onResult(Object object) {
                wait[0] = false;
            }

            @Override
            public void onError(String error) {
                wait[0] = false;
            }
        }, Scene);

        while (wait[0]) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static void saveNPC(List<Npc> Npc){
        for (Npc npc : Npc) {
            System.out.println(npc);
        }
    }

    public static void saveScenario(List<Room> Room){
        for (Room room : Room) {
            System.out.println(room);
        }
    }

    public static void saveWaypoint(List<Waypoint> waypoints){
        for (Waypoint waypoint : waypoints) {
            System.out.println(waypoint);
            saveWaypoint(waypoint);
        }
    }

    public static void saveWaypoint(Waypoint waypoint){
        final boolean[] wait = {true};
        Network network = new Network();
        network.saveWayPoint(new Network.Callback() {
            @Override
            public void onResult(Object object) {
                wait[0] = false;
            }

            @Override
            public void onError(String error) {
                wait[0] = false;
            }
        }, waypoint);

        while (wait[0]) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

    public static ScreenInfo parseXmlFile(String filePath) {
        ScreenInfo sceneData = new ScreenInfo();

        try {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(new File(filePath));
            doc.getDocumentElement().normalize();

            // 解析 SceneInfo
            Scene scene = new Scene();
            scene.setName(getTextContent(doc, "name"));
            scene.setTabOpenLocation(getTextContent(doc, "tabOpenLocation"));

            Element sizeElement = (Element) doc.getElementsByTagName("Size").item(0);
            if (sizeElement != null) {
                scene.setSizeX(Integer.parseInt(getTextContent(sizeElement, "x")));
                scene.setSizeY(Integer.parseInt(getTextContent(sizeElement, "y")));
            }

            String encountersStr = getTextContent(doc, "encounters");
            scene.setEncounters("是".equals(encountersStr) || "true".equals(encountersStr));
            sceneData.setScene(scene);

            // 解析 Npcs
            List<Npc> npcList = new ArrayList<>();
            NodeList npcNodes = doc.getElementsByTagName("Npc");
            for (int i = 0; i < npcNodes.getLength(); i++) {
                Element npcElement = (Element) npcNodes.item(i);
                Npc npc = new Npc();
                npc.setName(getTextContent(npcElement, "name"));
                npc.setType(getTextContent(npcElement, "type"));

                Element coordinate = (Element) npcElement.getElementsByTagName("Coordinate").item(0);
                if (coordinate != null) {
                    npc.setX(Integer.parseInt(getTextContent(coordinate, "x")));
                    npc.setY(Integer.parseInt(getTextContent(coordinate, "y")));
                }

                List<String> dialogues = new ArrayList<>();
                NodeList dialogueNodes = npcElement.getElementsByTagName("dialogue");
                for (int j = 0; j < dialogueNodes.getLength(); j++) {
                    Node node = dialogueNodes.item(j);
                    if (node.hasChildNodes()) {
                        dialogues.add(node.getFirstChild().getTextContent());
                    }
                }
                npc.setDialogues(dialogues);

                npcList.add(npc);
            }
            sceneData.setNpc(npcList);

            // 解析 Scenarios（rooms）
            // 注意：XML 中没有提供 room 的具体信息，这里可以留空或根据实际情况填充
            sceneData.setRoomList(new ArrayList<>());

            // 解析 Waypoints
            List<Waypoint> waypointList = new ArrayList<>();
            NodeList wayPointNodes = doc.getElementsByTagName("WayPoint");
            for (int i = 0; i < wayPointNodes.getLength(); i++) {
                Element wpElement = (Element) wayPointNodes.item(i);
                Waypoint wp = new Waypoint();

                wp.setType(getTextContent(wpElement, "type"));

                Element aperture = (Element) wpElement.getElementsByTagName("aperture").item(0);
                if (aperture != null) {
                    wp.setApertureX(Integer.parseInt(getTextContent(aperture, "x")));
                    wp.setApertureY(Integer.parseInt(getTextContent(aperture, "y")));
                }

                Element startPoint = (Element) wpElement.getElementsByTagName("startPoint").item(0);
                if (startPoint != null) {
                    wp.setStartPointX(Integer.parseInt(getTextContent(startPoint, "x")));
                    wp.setStartPointY(Integer.parseInt(getTextContent(startPoint, "y")));
                    wp.setStartNote(getTextContent(wpElement, "startNote"));
                }

                Element clockPoint = (Element) wpElement.getElementsByTagName("clockPoint").item(0);
                if (clockPoint != null) {
                    wp.setClockPointX(Integer.parseInt(getTextContent(clockPoint, "x")));
                    wp.setClockPointY(Integer.parseInt(getTextContent(clockPoint, "y")));
                }

                wp.setEndNote(getTextContent(wpElement, "endNote"));
                wp.setRoom(getTextContent(wpElement, "room"));

                waypointList.add(wp);
            }
            sceneData.setWaypointList(waypointList);

        } catch (Exception ex) {
            LOGGER.log(Level.SEVERE, "Error parsing XML file", ex);
        }

        return sceneData;
    }

    private static String getTextContent(Element parent, String tagName) {
        NodeList nodes = parent.getElementsByTagName(tagName);
        if (nodes.getLength() > 0 && nodes.item(0).hasChildNodes()) {
            return nodes.item(0).getFirstChild().getTextContent();
        }
        return null;
    }

    private static String getTextContent(Document doc, String tagName) {
        NodeList nodes = doc.getElementsByTagName(tagName);
        if (nodes.getLength() > 0 && nodes.item(0).hasChildNodes()) {
            return nodes.item(0).getFirstChild().getTextContent();
        }
        return null;
    }
}
